package cn.imatu.framework.tool.core;

import cn.imatu.framework.tool.core.exception.UtilException;
import net.sourceforge.pinyin4j.PinyinHelper;
import net.sourceforge.pinyin4j.format.HanyuPinyinCaseType;
import net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat;
import net.sourceforge.pinyin4j.format.HanyuPinyinToneType;
import net.sourceforge.pinyin4j.format.HanyuPinyinVCharType;
import net.sourceforge.pinyin4j.format.exception.BadHanyuPinyinOutputFormatCombination;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author shenguangyang
 */
public class InputCoder {
    private static final Logger log = LoggerFactory.getLogger(InputCoder.class);

    public static String getPinYin(String inputString) {
        if (StringUtils.isEmpty(inputString)) {
            return "";
        } else {
            HanyuPinyinOutputFormat format = new HanyuPinyinOutputFormat();
            format.setCaseType(HanyuPinyinCaseType.UPPERCASE);
            format.setToneType(HanyuPinyinToneType.WITHOUT_TONE);
            format.setVCharType(HanyuPinyinVCharType.WITH_V);
            char[] input = inputString.trim().toCharArray();
            StringBuilder output = new StringBuilder();

            try {
                for (char c : input) {
                    if (Character.toString(c).matches("[\\u4E00-\\u9FA5]+")) {
                        String[] temp = PinyinHelper.toHanyuPinyinStringArray(c, format);
                        output.append(temp[0]);
                    } else {
                        output.append(c);
                    }
                }
            } catch (BadHanyuPinyinOutputFormatCombination e) {
                log.error("{}", e.getMessage());
                log.debug("", e);
                throw new UtilException("get pin yin error");
            }

            return output.toString();
        }
    }

    public static String getFirstSpell(String chinese) {
        if (StringUtils.isEmpty(chinese)) {
            return "";
        } else {
            StringBuilder sb = new StringBuilder();
            char[] arr = chinese.toCharArray();
            HanyuPinyinOutputFormat defaultFormat = new HanyuPinyinOutputFormat();
            defaultFormat.setCaseType(HanyuPinyinCaseType.UPPERCASE);
            defaultFormat.setToneType(HanyuPinyinToneType.WITHOUT_TONE);

            for (char c : arr) {
                if (c > 128) {
                    try {
                        String[] temp = PinyinHelper.toHanyuPinyinStringArray(c, defaultFormat);
                        if (temp != null) {
                            sb.append(temp[0].charAt(0));
                        }
                    } catch (BadHanyuPinyinOutputFormatCombination e) {
                        log.error("{}", e.getMessage());
                        log.debug("", e);
                        throw new UtilException("get pin yin error");
                    }
                } else {
                    sb.append(c);
                }
            }

            return sb.toString().replaceAll("\\W", "").trim();
        }
    }

    public static String getFullSpell(String chinese) {
        if (StringUtils.isEmpty(chinese)) {
            return "";
        } else {
            StringBuilder sb = new StringBuilder();
            char[] arr = chinese.toCharArray();
            HanyuPinyinOutputFormat defaultFormat = new HanyuPinyinOutputFormat();
            defaultFormat.setCaseType(HanyuPinyinCaseType.UPPERCASE);
            defaultFormat.setToneType(HanyuPinyinToneType.WITHOUT_TONE);

            for (char c : arr) {
                if (c > 128) {
                    try {
                        sb.append(PinyinHelper.toHanyuPinyinStringArray(c, defaultFormat)[0]);
                    } catch (BadHanyuPinyinOutputFormatCombination e) {
                        log.error("{}", e.getMessage());
                        log.debug("", e);
                        throw new UtilException("get pin yin error");
                    }
                } else {
                    sb.append(c);
                }
            }

            return sb.toString();
        }
    }

    public static boolean isChineseByName(String str) {
        if (str == null) {
            return false;
        } else {
            String reg = "\\p{InCJK Unified Ideographs}&&\\P{Cn}";
            Pattern pattern = Pattern.compile(reg);
            return pattern.matcher(str.trim()).find();
        }
    }

    public static boolean isChinese(String strName) {
        char[] ch = strName.toCharArray();

        for (char c : ch) {
            if (isChinese(c)) {
                return true;
            }
        }

        return false;
    }

    public static boolean isChinese(char c) {
        Character.UnicodeBlock ub = Character.UnicodeBlock.of(c);
        return ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS || ub == Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS || ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A || ub == Character.UnicodeBlock.GENERAL_PUNCTUATION || ub == Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION || ub == Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS;
    }

    public static boolean isMessyCode(String strName) {
        Pattern p = Pattern.compile("\\s*|\t*|\r*|\n*");
        Matcher m = p.matcher(strName);
        String after = m.replaceAll("");
        String temp = after.replaceAll("\\p{P}", "");
        char[] ch = temp.trim().toCharArray();
        float chLength = 0.0F;
        float count = 0.0F;

        for (char c : ch) {
            if (!Character.isLetterOrDigit(c)) {
                if (!isChinese(c)) {
                    ++count;
                }

                ++chLength;
            }
        }
        float result = count / chLength;
        return (double) result > 0.4;
    }
}
